package br.com.simulador.model;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.persistence.EntityManager;

//import org.apache.lucene.analysis.br.BrazilianAnalyzer;
//import org.apache.lucene.queryParser.ParseException;
//import org.apache.lucene.queryParser.QueryParser;
//import org.apache.lucene.search.Sort;
//import org.apache.lucene.search.SortField;
//import org.apache.lucene.util.Version;
//import org.hibernate.search.jpa.FullTextEntityManager;
//import org.hibernate.search.jpa.FullTextQuery;
import org.jboss.seam.annotations.In;

/**
 * Classe de Data Access Object que contém os métodos básicos de manipulação dos
 * dados. Toda classe específica deve extender desta classe.
 * 
 * @author osman
 * 
 * @param <T>
 *            A classe de entidade que será manipulada
 * @param <ID>
 *            O tipo da chave primária da entidade.
 */
public class BaseDao<T, ID>  {

    private static final long serialVersionUID = 1L;
    public static final int MAXRESULTS = 50;

    @In
    protected EntityManager entityManager;

    private Class<T> persistenceClazz = null;

    /**
     * Retorna um busca com todos os cadastros de uma entidade na base de dados.
     * 
     * @return java.util.List<T> A lista contendo as entidades retornadas.
     * @throws ManyResultsException
     *             Exceção lançada caso o número de retornos seja maior do que o
     *             previsto. Hoje este número máximo é 50 por consulta.
     */
    @SuppressWarnings("unchecked")
    public List<T> findAll()  {
    	List<T> retorno = entityManager.createQuery("SELECT c FROM " + getPersistenceClass().getSimpleName() + " c").setMaxResults(MAXRESULTS).getResultList();
		return retorno;
    }

    /**
     * Retorna uma entidade pela sua chave primária.
     * 
     * @param id
     *            o Identificador da entidade
     * @return T A entidade retornada.
     */

    public T findById(ID id) {
	return entityManager.find(getPersistenceClass(), id);

    }

    /**
     * Insere o objeto correspondente do banco de dados.
     * 
     * @param entidade
     *            A entidade a ser inserida
     * 
     */

    public void persist(T entidade) {
	entityManager.persist(entidade);
	entityManager.flush();
    }

    /**
     * Remove o objeto correspondente do banco de dados.
     * 
     * @param entidade
     *            A entidade a ser removida
     * 
     */

    public void remove(T entidade) {
	entityManager.remove(entidade);
	entityManager.flush();
    }

    /**
     * Retorna a classe persistente.
     * 
     * @return Class<T> A Classe persistente
     */
    @SuppressWarnings("unchecked")
    protected Class<T> getPersistenceClass() {
	if (persistenceClazz == null) {
	    persistenceClazz = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}
	return persistenceClazz;
    }



}
